﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using Conexion;
using System.IO;
using System.Windows.Forms;

namespace Cliente
{
    class RequestManager
    {

        private Config conf = null;
        private const string CMD_RAM = "01";
        private const string CMD_CPU = "02";
        private const string CMD_DISCO = "03";
        private const string CMD_SERV = "04";
        private const string CMD_ERROR = "05";
        private List<string> servidores = new List<string>(); // cambiarlo por array de servidores
        public ClientForm ventana = null;

        public RequestManager(Config conf, ClientForm form)
        {
            this.conf = conf;
            this.ventana = form;
        }

        public int ConsultarManager(string cmd)
        {
            TcpClient cliente = null;
            int cantServidores = 0;
            try
            {
                cliente = ClientTCP.obtenerTcpClient(conf.Ip_manager, conf.Puerto_manager);


                string request = "";

                switch (cmd)
                {
                    case CMD_RAM:
                        request = crearComando(CMD_RAM);
                        break;
                    case CMD_DISCO:
                        request = crearComando(CMD_DISCO);
                        break;
                    case CMD_CPU:
                        request = crearComando(CMD_CPU);
                        break;
                    case CMD_SERV:
                        request = crearComando(CMD_SERV);
                        break;
                    default:
                        Console.WriteLine("Default case");
                        break;
                }

                // LOG "Sending data"
                StreamWriter str = new StreamWriter(cliente.GetStream());
                str.Write(request);
                str.Flush();

                //LOG "Comienzo a escuchar"
                string hdr = "";
                NetworkStream ns;
                byte[] datos = new byte[1024];
                string data = "";
                char[] cero = new char[] { '0' };

                ns = cliente.GetStream();
                ns.Read(datos, 0, 3);
                hdr = Encoding.UTF8.GetString(datos).Substring(0, 3);

                if (hdr.Equals("RES"))
                {
                    string respuesta = "";
                    ns.Read(datos, 0, 2);
                    string cmdRecibido = Encoding.UTF8.GetString(datos).Substring(0, 2);
                    if (cmdRecibido.Equals(cmd))
                    {
                        switch (cmd)
                        {
                            case CMD_RAM:
                                {
                                    ns.Read(datos, 0, 15);
                                    data = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                    if (string.IsNullOrEmpty(data))
                                        data = "0";
                                    if (data.StartsWith(","))
                                        data = "0"+data;
                                    respuesta += "Ram Total: " + data + " MB" + "\n";
                                    ns.Read(datos, 0, 15);
                                    data = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                    if (string.IsNullOrEmpty(data))
                                        data = "0";
                                    if (data.StartsWith(","))
                                        data = "0" + data;
                                    respuesta += "Ram Libre: " + data + " MB";
                                    Label lbl = (Label)ObtenerControl("lblRes");
                                    lbl.Text = respuesta;
                                    break;
                                }
                            case CMD_DISCO:
                                {
                                    ns.Read(datos, 0, 15);
                                    data = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                    if (string.IsNullOrEmpty(data))
                                        data = "0";
                                    respuesta += "Disco Total: " + data + " GB" + "\n";
                                    ns.Read(datos, 0, 15);
                                    data = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                    if (string.IsNullOrEmpty(data))
                                        data = "0";
                                    respuesta += "Disco Libre: " + data + " GB";
                                    Label lbl = (Label)ObtenerControl("lblRes");
                                    lbl.Text = respuesta;
                                    break;
                                }
                            case CMD_CPU:
                                {
                                    ns.Read(datos, 0, 15);
                                    data = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                    if (string.IsNullOrEmpty(data))
                                        data = "0";

                                    respuesta += "Uso Cpu: " + data + " %" + "\n";
                                    Label lbl = (Label)ObtenerControl("lblRes");
                                    lbl.Text = respuesta;
                                    break;
                                }
                            case CMD_SERV:
                                {
                                    ns.Read(datos, 0, 1);
                                    cantServidores = int.Parse(Encoding.UTF8.GetString(datos).Substring(0, 1));
                                    string idServidor = "";
                                    string nombreServidor = "";
                                    List<DataServer> servidores = new List<DataServer>();
                                    for (int i = 0; i < cantServidores; i++)
                                    {
                                        ns.Read(datos, 0, 4);
                                        idServidor = Encoding.UTF8.GetString(datos).Substring(0, 4);
                                        ns.Read(datos, 0, 15);
                                        nombreServidor = Encoding.UTF8.GetString(datos).Substring(0, 15).TrimStart(cero);
                                        servidores.Add(new DataServer(idServidor, nombreServidor));
                                    }
                                    // lstServers.Items.Clear();
                                    ListBox lista = (ListBox)ObtenerControl("lstServers");
                                    lista.DataSource = servidores;
                                    break;
                                }
                            default:
                                Console.WriteLine("Default case");
                                break;
                        }
                    }
                    else
                    {
                        if (cmdRecibido.Equals(CMD_ERROR))
                        {
                            Label lbl = (Label)ObtenerControl("lblRes");
                            lbl.Text = "El servidor no responde";
                        }
                    }
                }
                return cantServidores;
            }
            catch (Exception ex)
            {
                MessageBox.Show("No se pudo realizar conexion con el manager.");
                return 0;
            }
        }

        /// <summary>
        /// FORMATO:
        ///     HEADER   |   CMD    |    LARGO         |   DATOS
        ///     REQ      |   0X     | {largo MAX ip}   |    IP
        ///      3       |   2      |     2            |  7 - 15
        /// EJ:  REQ     |   01     |    12            | 192.168.10.5  
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private string crearComando(string cmd)
        {
            string comando = "REQ";
            if (cmd.Equals(CMD_SERV))
            {
                comando += cmd;
            }
            else
            {
                ListBox lista = (ListBox)ObtenerControl("lstServers");
                DataServer s = (DataServer)(lista.SelectedItem);
                if (s != null)
                {
                    switch (cmd)
                    {
                        case CMD_CPU:
                            comando += CMD_CPU;
                            break;

                        case CMD_DISCO:
                            comando += CMD_DISCO;
                            break;

                        case CMD_RAM:
                            comando += CMD_RAM;
                            break;

                        case CMD_SERV:
                            comando += CMD_SERV;
                            break;

                        default:
                            break;
                    }

                    comando += s.Identificador;
                }
            }
            return comando;
        }


        private Control ObtenerControl(string cmd)
        {
            Control[] controles = ventana.Controls.Find(cmd, true);

            return controles[0];
        }

    }
}
